package com.mmall.concurrency.lock;

import com.mmall.concurrency.annotations.NotThreadSafe;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@NotThreadSafe
public class ReentrantLockDemo {
    public static int clientTotal = 5000;
    public static int threadTotal = 200;
    public static int count = 0;
    // 定义锁
    private static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws Exception{
        // 定义线程池和信号量
        ExecutorService executorService = Executors.newCachedThreadPool();
        final Semaphore semaphore = new Semaphore(threadTotal);
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i = 0; i< clientTotal; i++){
            executorService.execute( () -> {
                // 线程里执行，加解锁，中间执行
                try {
                    semaphore.acquire();
                    add();
                    semaphore.release();
                }catch (Exception e){
                    log.error("信号量捕获异常 ");
                    e.printStackTrace();
                }
                countDownLatch.countDown();
            } );
        } // for
        countDownLatch.await();
        log.info("{}",count);
        executorService.shutdown();
    }

    private static void add(){
        lock.lock();
        try{
            count++;
        }catch (Exception e){
            log.error("{} add 报错", e.getMessage());
        }finally {
            lock.unlock();
        }
    }
}
